#pragma once
#include <cstdint>
#include <modbus/modbus.h>
#include <string>
#include <motor.hpp>

class Motor_RS485
{
  public:
    Motor_RS485();
    ~Motor_RS485();
    bool InitBySerialDevice(std::string dev, int baud, MotorConfig cfg, bool debug);
    // Use this function,motor instance will not free ModBus automatically.
    bool InitDevice(modbus_t *modbus, MotorConfig cfg);
    bool CheckDevice();
    float GetRPM();
    bool SetControlMode(ControlMode mode);
    void SetRPM(float value);
    void SetPWM(float precent);
    void SetCurrent(float mA);
    void SendHeartBeat();
    // Motor must be active first, then can be readed or wrtien
    void Select();
    static modbus_t *CreatModBusInstance(std::string dev, int baudrate, bool debug);

  private:
    enum class RegeisterAddress : int
    {
        ErrorMessage = 5000,
        RealERPM = 5001,
        RealDuty = 5003,
        RealPower = 5004,
        RealInputVoltage = 5004,
        RealCurrent = 5006,
        RealBusCurrent = 5007,
        RealTemperature = 5008,
        RealAngle = 5009,
        RealPosition = 5010,
        ZeroState = 5012,
        HeartBeat = 6000,
        ControlMode = 6001,
        SetCurrent = 6002,
        SetERPM = 6003,
        SetDuty = 6005,
        SetAbsolutePosition = 6006,
        SetRelateTargetPosition = 6008,
        SetRelatePosition = 6010,
        LocatePosition = 6012,
        SetBrakeCurrent = 6014,
        SetHandBrakeCurrent = 6015,
        //... there are some other values
    };

    modbus_t *modBusCtx;
    MotorConfig config;
    bool hasError;
    bool useSharedCtx;
    uint16_t heartBeatValue;
};